home *** CD-ROM | disk | FTP | other *** search
/ Aminet 34 / Aminet 34 (2000)(Schatztruhe)[!][Dec 1999].iso / Aminet / util / gnu / unixcmds.lha / unixcmds / src / tr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-06  |  4.8 KB  |  178 lines

  1. /* tr - translate characters            Author: Michiel Huisjes */
  2. /* Usage: tr [-cds] [string1 [string2]]
  3.  *      c: take complement of string1
  4.  *      d: delete input characters coded string1
  5.  *      s: squeeze multiple output characters of string2 into one character
  6.  */
  7.  
  8. #define BUFFER_SIZE     1024
  9. #define ASCII           0377
  10.  
  11. typedef char Bool;
  12.  
  13. #define TRUE    1
  14. #define FALSE   0
  15.  
  16. #define NIL_PTR         ((char *) 0)
  17.  
  18. Bool com_fl, del_fl, sq_fl;
  19.  
  20. unsigned char output[BUFFER_SIZE], input[BUFFER_SIZE];
  21. unsigned char vector[ASCII + 1];
  22. Bool invec[ASCII + 1], outvec[ASCII + 1];
  23.  
  24. short in_index, out_index;
  25.  
  26. #include <stdio.h>
  27. #include <sys/types.h>
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <unistd.h>
  31.  
  32. int main  (int argc, char **argv);
  33. void convert  (void);
  34. void map  (unsigned char *string1, unsigned char *string2);
  35. void expand  (char *arg, unsigned char *buffer);
  36. void complement  (unsigned char *buffer);
  37.  
  38. int main(argc, argv)
  39. /* [<][>][^][v][top][bottom][index][help] */
  40. int argc;
  41. char *argv[];
  42. {
  43.   register unsigned char *ptr;
  44.   int index = 1;
  45.   short i;
  46.  
  47.   if (argc > 1 && argv[index][0] == '-') {
  48.         for (ptr = (unsigned char *) &argv[index][1]; *ptr; ptr++) {
  49.                 switch (*ptr) {
  50.                     case 'c':   com_fl = TRUE;  break;
  51.                     case 'd':   del_fl = TRUE;  break;
  52.                     case 's':   sq_fl = TRUE;   break;
  53.                     default:
  54.                         printf("Usage: tr [-cds] [string1 [string2]].\n");
  55.                         exit(1);
  56.                 }
  57.         }
  58.         index++;
  59.   }
  60.   for (i = 0; i <= ASCII; i++) {
  61.         vector[i] = i;
  62.         invec[i] = outvec[i] = FALSE;
  63.   }
  64.  
  65.   if (argv[index] != NIL_PTR) {
  66.         expand(argv[index++], input);
  67.         if (com_fl) complement(input);
  68.         if (argv[index] != NIL_PTR) expand(argv[index], output);
  69.         if (argv[index] != NIL_PTR) map(input, output);
  70.         for (ptr = input; *ptr; ptr++) invec[*ptr] = TRUE;
  71.         for (ptr = output; *ptr; ptr++) outvec[*ptr] = TRUE;
  72.   }
  73.   convert();
  74.   return(0);
  75. }
  76.  
  77. void convert()
  78. /* [<][>][^][v][top][bottom][index][help] */
  79. {
  80.   short read_chars = 0;
  81.   short c, coded;
  82.   short last = -1;
  83.  
  84.   for (;;) {
  85.         if (in_index == read_chars) {
  86.                 if ((read_chars = read(0, (char *)input, BUFFER_SIZE)) <= 0) {
  87.                         if (write(1, (char *)output, out_index) != out_index)
  88.                                 printf("Bad write\n");
  89.                         exit(0);
  90.                 }
  91.                 in_index = 0;
  92.         }
  93.         c = input[in_index++];
  94.         coded = vector[c];
  95.         if (del_fl && invec[c]) continue;
  96.         if (sq_fl && last == coded && outvec[coded]) continue;
  97.         output[out_index++] = last = coded;
  98.         if (out_index == BUFFER_SIZE) {
  99.                 if (write(1, (char *)output, out_index) != out_index) {
  100.                         printf("Bad write\n");
  101.                         exit(1);
  102.                 }
  103.                 out_index = 0;
  104.         }
  105.   }
  106.  
  107.   /* NOTREACHED */
  108. }
  109.  
  110. void map(string1, string2)
  111. /* [<][>][^][v][top][bottom][index][help] */
  112. register unsigned char *string1, *string2;
  113. {
  114.   unsigned char last=0;
  115.  
  116.   while (*string1) {
  117.         if (*string2 == '\0')
  118.                 vector[*string1] = last;
  119.         else
  120.                 vector[*string1] = last = *string2++;
  121.         string1++;
  122.   }
  123. }
  124.  
  125. void expand(arg, buffer)
  126. /* [<][>][^][v][top][bottom][index][help] */
  127. register char *arg;
  128. register unsigned char *buffer;
  129. {
  130.   int i, ac;
  131.  
  132.   while (*arg) {
  133.         if (*arg == '\\') {
  134.                 arg++;
  135.                 i = ac = 0;
  136.                 if (*arg >= '0' && *arg <= '7') {
  137.                         do {
  138.                                 ac = (ac << 3) + *arg++ - '0';
  139.                                 i++;
  140.                         } while (i < 4 && *arg >= '0' && *arg <= '7');
  141.                         *buffer++ = ac;
  142.                 } else if (*arg != '\0')
  143.                         *buffer++ = *arg++;
  144.         } else if (*arg == '[') {
  145.                 arg++;
  146.                 i = *arg++;
  147.                 if (*arg++ != '-') {
  148.                         *buffer++ = '[';
  149.                         arg -= 2;
  150.                         continue;
  151.                 }
  152.                 ac = *arg++;
  153.                 while (i <= ac) *buffer++ = i++;
  154.                 arg++;          /* Skip ']' */
  155.         } else
  156.                 *buffer++ = *arg++;
  157.   }
  158. }
  159.  
  160. void complement(buffer)
  161. /* [<][>][^][v][top][bottom][index][help] */
  162. unsigned char *buffer;
  163. {
  164.   register unsigned char *ptr;
  165.   register short i, index;
  166.   unsigned char conv[ASCII + 2];
  167.  
  168.   index = 0;
  169.   for (i = 1; i <= ASCII; i++) {
  170.         for (ptr = buffer; *ptr; ptr++)
  171.                 if (*ptr == i) break;
  172.         if (*ptr == '\0') conv[index++] = i & ASCII;
  173.   }
  174.   conv[index] = '\0';
  175.   strcpy((char *)buffer, (char *)conv);
  176. }
  177. /* [<][>][^][v][top][bottom][index][help] */
  178.